package cn.itsource.aigou.service.impl;

import cn.itsource.aigou.client.PageClient;
import cn.itsource.aigou.client.ProductESClient;
import cn.itsource.aigou.domain.*;
import cn.itsource.aigou.mapper.*;
import cn.itsource.aigou.query.ProductQuery;
import cn.itsource.aigou.service.IProductService;
import cn.itsource.aigou.util.PageList;
import cn.itsource.aigou.util.StrUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * <p>
 * 商品 服务实现类
 * </p>
 *
 * @author solargen
 * @since 2019-08-24
 */
@Service
@Transactional(propagation = Propagation.SUPPORTS,readOnly = true)
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements IProductService {

    @Autowired
    private ProductExtMapper productExtMapper;
    @Autowired
    private SpecificationMapper specificationMapper;
    @Autowired
    private SkuMapper skuMapper;
    @Autowired
    private ProductESClient productESClient;
    @Autowired
    private ProductTypeMapper productTypeMapper;
    @Autowired
    private BrandMapper brandMapper;
    @Autowired
    private PageClient pageClient;

    /**
     * 在线商城搜索上架商品
     * @param param
     * @return
     */
    @Override
    public PageList<ProductDoc> searchProduct(Map<String,Object> param) {
        PageList<ProductDoc> pageList = productESClient.search(param);
        return pageList;
    }

    /**
     * 批量上架
     * @param idList
     */
    @Override
    @Transactional
    public void onSale(List<Long> idList) {
        //修改数据库的状态和上架时间
        baseMapper.onSale(new Date().getTime(),idList);
        //查询商品信息
        List<Product> products = baseMapper.selectBatchIds(idList);
        //保存到ES中
        List<ProductDoc> productDocs = products2ProductDocs(products);
        //页面静态化
        for (Product product : products) {
            genStaticDetailPage(product);
        }
        productESClient.save(productDocs);
    }

    /**
     * 商品详情页页面静态化
     * @param product
     */
    private void genStaticDetailPage(Product product) {

        String templatePath = "D:\\workspace\\aigou-parent\\aigou-product\\product-service\\src\\main\\resources\\template\\product-detail.vm";

        String targetPath = "D:\\workspace\\aigou-web-parent\\ecommerce\\detail\\"+product.getId()+".html";

        Map<String,Object> data = new HashMap<>();//$model
        data.put("product", product);
        //面包屑的数据
        Long productTypeId = product.getProductTypeId();
        List<Map<String, Object>> crubms = loadCrubms(productTypeId);
        data.put("crumbs",crubms);
        //媒体属性封装到List<List<String>>中转成json字符串放入到model中
        String[] medisStrArr = StrUtils.splitStr2StrArr(product.getMedias());
        List<List<String>> mediaList = new ArrayList<>();
        String fastdfsHost = "http://172.16.2.128";
        for (String medisStr : medisStrArr) {
            List<String> list = new ArrayList<>();
            list.add(fastdfsHost+medisStr);
            list.add(fastdfsHost+medisStr);
            list.add(fastdfsHost+medisStr);
            mediaList.add(list);
        }
        String mediaJson = JSON.toJSONString(mediaList);
        data.put("medias", mediaJson);
        //sku属性 -- 扩展表
        ProductExt productExt = productExtMapper.selectOne(new QueryWrapper<ProductExt>().eq("product_id", product.getId()));
        String skuPropertiesStr = productExt.getSkuProperties();
        List<Specification> skuProperties = JSON.parseArray(skuPropertiesStr, Specification.class);
        data.put("skuProperties", skuProperties);
        data.put("skuPropertiesStr",skuPropertiesStr);
        //显示属性
        List<Specification> viewProperties = JSON.parseArray(productExt.getViewProperties(), Specification.class);
        data.put("viewProperties", viewProperties);
        //商品详情
        data.put("richContent", productExt.getRichContent());


        pageClient.genStaticPage(templatePath , targetPath, data);


    }


    /**
     * 加载类型面包屑
     * @param productTypeId
     * @return
     */
    private List<Map<String, Object>> loadCrubms(Long productTypeId) {
        //获取到各个级别的类型ID -- path字段
        ProductType productType = productTypeMapper.selectById(productTypeId);
        String path = productType.getPath();
        //查询各个级别的类型
        path = path.replaceAll("\\.", ",");
        path = path.substring(1);
        List<Long> ids = StrUtils.splitStr2LongArr(path);
        List<ProductType> productTypes = productTypeMapper.selectBatchIds(ids);
        //查询兄弟，组装结果List返回
        List<Map<String, Object>> list = new ArrayList<>();
        for (ProductType type : productTypes) {
            Map<String, Object> map = new HashMap<>();
            map.put("current", type);//当前类型
            //兄弟类型
            List<ProductType> otherTypes = productTypeMapper.selectList(new QueryWrapper<ProductType>()
                    .eq("pid", type.getPid()));
            map.put("otherTypes", otherTypes);
            list.add(map);
        }
        return list;
    }


    /**
     * 批量下架
     * @param idList
     */
    @Override
    public void offSale(List<Long> idList) {
        //修改数据库的状态和下架时间
        baseMapper.offSale(new Date().getTime(),idList);
        //删除ES中的数据
        List<ProductDoc> productDocList = new ArrayList<>();
        for (Long id : idList) {
            ProductDoc doc = new ProductDoc();
            doc.setId(id);
            productDocList.add(doc);
        }
        productESClient.delete(productDocList);
    }


    /**
     * 集合转换
     * @param products
     * @return
     */
    private List<ProductDoc> products2ProductDocs(List<Product> products) {
        List<ProductDoc> productDocList = new ArrayList<>();
        for (Product product : products) {
            ProductDoc productDoc = product2ProductDoc(product);
            productDocList.add(productDoc);
        }
        return productDocList;
    }

    /**
     * 对象转换
     * @param product
     * @return
     */
    private ProductDoc product2ProductDoc(Product product) {
        ProductDoc productDoc = new ProductDoc();
        productDoc.setId(product.getId());
        //******all字段  商品标题  商品副标题  商品类型名称 商品品牌名称******
        StringBuilder sb = new StringBuilder();
        sb.append(product.getName());
        sb.append(" ");
        sb.append(product.getSubName());
        sb.append(" ");
        String productTypeName = productTypeMapper.selectById(product.getProductTypeId()).getName();
        sb.append(productTypeName);
        sb.append(" ");
        String brandName = brandMapper.selectById(product.getBrandId()).getName();
        sb.append(brandName);
        productDoc.setAll(sb.toString());
        //*****************all字段  end*******************************
        productDoc.setProductTypeId(product.getProductTypeId());

        //*******************价格 start********************************
        List<Sku> skuList = skuMapper.selectList(new QueryWrapper<Sku>().eq("product_id", product.getId()));
        Integer maxPrice = skuList.get(0).getPrice();
        Integer minPrice = skuList.get(0).getPrice();
        for (Sku sku : skuList) {
            if(sku.getPrice()>=maxPrice){
                maxPrice = sku.getPrice();
            }
            if(sku.getPrice()<=minPrice){
                minPrice = sku.getPrice();
            }
        }
        productDoc.setMinPrice(minPrice);
        productDoc.setMaxPrice(maxPrice);
        //*******************价格 end********************************

        productDoc.setSaleCount(product.getSaleCount());
        productDoc.setOnSaleTime(product.getOnSaleTime());
        productDoc.setCommentCount(product.getCommentCount());
        productDoc.setViewCount(product.getViewCount());
        productDoc.setName(product.getName());
        productDoc.setSubName(product.getSubName());
        productDoc.setMedias(product.getMedias());

        //*******************显示属性 &  sku属性**************************
        ProductExt productExt = productExtMapper.selectOne(new QueryWrapper<ProductExt>().eq("product_id", product.getId()));
        productDoc.setSkuProperties(productExt.getSkuProperties());
        productDoc.setViewProperties(productExt.getViewProperties());
        return productDoc;
    }


    /**
     * 修改商品的SKU属性
     * @param productId
     * @param skuProperties
     * @param skus
     */
    @Override
    @Transactional
    public void updateSkuProperties(long productId, List<Specification> skuProperties, List<Map<String, Object>> skus) {
        //改几张表？？？
        //修改商品扩展表的skuProperties列
        String skuPropertiesStr = JSON.toJSONString(skuProperties);
        productExtMapper.updateSkuProperties(productId,skuPropertiesStr);
        //根据productId删除sku表的数据
        skuMapper.delete(new QueryWrapper<Sku>().eq("product_id", productId));
        //向sku表中添加数据
        //将List<Map<String, Object>>转成 List<Sku>
        List<Sku> skuList = mapListToSkuList(skus,productId);
        skuList.forEach(sku->{
            skuMapper.insert(sku);
        });
    }


    private List<Sku> mapListToSkuList(List<Map<String, Object>> skus,Long productId) {
        List<Sku> skuList = new ArrayList<>();
        for (Map<String, Object> skuMap : skus) {
            Sku sku = map2Sku(skuMap,productId);
            skuList.add(sku);
        }
        return skuList;
    }

    private Sku map2Sku(Map<String, Object> skuMap,Long productId) {
        Sku sku = new Sku();
        sku.setProductId(productId);
        sku.setCreateTime(new Date().getTime());
        //skuName
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, Object> entry : skuMap.entrySet()) {
            if("price".equals(entry.getKey())||"store".equals(entry.getKey())||"indexes".equals(entry.getKey())){
                continue;
            }
            sb.append(entry.getValue());
        }
        sku.setSkuName(sb.toString());
        sku.setPrice(Integer.parseInt((String)skuMap.get("price")));
        sku.setAvailableStock(Integer.parseInt((String) skuMap.get("store")));
        sku.setIndexs((String) skuMap.get("indexes"));
        return sku;
    }

    /**
     * 查询商品的Sku属性
     * @param productId
     * @return
     */
    @Override
    public List<Specification> getSkuProperties(Long productId) {
        ProductExt productExt = productExtMapper.selectOne(new QueryWrapper<ProductExt>().eq("product_id", productId));
        String skuProperties = productExt.getSkuProperties();
        if(StringUtils.isNotEmpty(skuProperties)){
            //[{id:1,specName:"年龄",options:["萝莉","御姐"]},{....}]
            List<Specification> specifications = JSON.parseArray(skuProperties, Specification.class);
            return specifications;
        }
        //查询属性表
        Long productTypeId = baseMapper.selectById(productId).getProductTypeId();
        List<Specification> specificationList = specificationMapper.selectList(new QueryWrapper<Specification>()
                .eq("product_type_id", productTypeId)
                .eq("isSku", 1));
        return specificationList;
    }



    /**
     * 修改显示属性
     * @param productId
     * @param viewProperties
     */
    @Override
    @Transactional
    public void updateViewProperties(Long productId, List<Specification> viewProperties) {
        String viewPropertiesStr = JSON.toJSONString(viewProperties);
        productExtMapper.updateViewProperties(productId,viewPropertiesStr);
    }


    /**
     * 查询商品的显示属性
     * @param productId
     * @return
     */
    @Override
    public List<Specification> getViewProperties(Long productId) {
        //先查询之前有没有设置过 -- 商品扩展表
        ProductExt productExt = productExtMapper.selectOne(new QueryWrapper<ProductExt>().eq("product_id", productId));
        String viewProperties = productExt.getViewProperties();
        if(StringUtils.isNotEmpty(viewProperties)){
            //不为空
            //[{id:1,name:"材质",value:"金属"},{id:2,name:"容量",value:"10L"}]
            List<Specification> specifications = JSON.parseArray(viewProperties, Specification.class);
            return specifications;
        }
        //再查询属性表
        Long productTypeId = baseMapper.selectById(productId).getProductTypeId();
        List<Specification> specificationList = specificationMapper.selectList(new QueryWrapper<Specification>()
                .eq("product_type_id", productTypeId)
                .eq("isSku", 0));
        //[{id:1,name:"材质",value:null},{id:2,name:"容量",value:null}]
        return specificationList;
    }


    /**
     * 高级分页查询
     * @param query
     * @return
     */
    @Override
    public PageList<Product> queryPage(ProductQuery query) {
        IPage<Product> iPage = baseMapper.selectPage(new Page<>(query.getPage(), query.getRows()),
                new QueryWrapper<Product>().like("tp.name", query.getKeyword()).or().like("tp.subName", query.getKeyword()));
        return new PageList<>(iPage.getTotal(),iPage.getRecords());
    }


    /**
     * 重写save，向商品表和商品的扩展表中添加数据
     * @param entity
     * @return
     */
    @Transactional
    @Override
    public boolean save(Product entity) {
        //插入商品后马上返回商品的主键,mybatis中 useGeneratedKeys=true
        //mybatisplus已经帮我们实现了这个功能，直接用
        baseMapper.insert(entity);//商品表

        //商品扩展表
        ProductExt productExt = entity.getProductExt();
        productExt.setProductId(entity.getId());
        productExtMapper.insert(productExt);

        return true;
    }
}
